
/*
 *
 *
 * @name     attributes.numeric
 * @param    attributes.culture     
 * @param    attributes.callbackErrorFormat     A function that runs if the date is not valid
 * @param    attributes.callbackNoError     A function that runs if the date is valid
 *
 */
 
jQuery.fn.date = function(attributes)
{
	if (!attributes) 
    {attributes = {};}
	attributes.culture = attributes.culture || "FR";
	attributes.callbackErrorFormat = typeof attributes.callbackErrorFormat == "function" ? attributes.callbackErrorFormat : function(){};
	attributes.callbackNoError = typeof attributes.callbackNoError == "function" ? attributes.callbackNoError : function(){};
	this.keypress(
		function(e)
		{
			//noMoreBackspace();
			var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
			// allow enter/return key (only when in an input box)
			if(key == 13 && this.nodeName.toLowerCase() == "input")
			{
				return true;
			}
			else if(key == 13)
			{
				return false;
			}
			var allow = false;
			// allow Ctrl+A
			if((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) {return true;}
			// allow Ctrl+X (cut)
			if((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) {return true;}
			// allow Ctrl+C (copy)
			if((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) {return true;}
			// allow Ctrl+Z (undo)
			if((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) {return true;}
			// allow or deny Ctrl+V (paste), Shift+Ins
			if((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */ || (e.shiftKey && key == 45)) {return true;}
			// if a number was not pressed
			if(key < 48 || key > 57)
			{
				/* '/' only allowed at 3rd and 6th position*/
				if((key == 47 && this.value.length == 2) || (key == 47 && this.value.length == 5)){return true;}
				
				// check for other keys that have special purposes
				if(
					key != 8 /* backspace */ &&	key != 9 /* tab */ && key != 13 /* enter */ &&	key != 35 /* end */ &&	key != 36 /* home */ && key != 37 /* left */ && key != 39 /* right */ && key != 46 /* del */)
          {
            allow = false;
          }
				else
          {
            // for detecting special keys (listed above)
            // IE does not support 'charCode' and ignores them in keypress anyway
            if(typeof e.charCode != "undefined")
            {
              // special keys have 'keyCode' and 'which' the same (e.g. backspace)
              if(e.keyCode == e.which && e.which != 0)
              {
                allow = true;
              }
              // or keyCode != 0 and 'charCode'/'which' = 0
              else if(e.keyCode != 0 && e.charCode == 0 && e.which == 0)
              {
                allow = true;
              }
            }
          }
			}
			else
			{	//If number pressed
				/* only allowed at 1,2,4,5,7,8,9,10th position*/
				if ((this.value.length == 0) || (this.value.length == 1) || (this.value.length == 3) || (this.value.length == 4) || (this.value.length == 6) || (this.value.length == 7) || (this.value.length == 8) || (this.value.length == 9))
					{allow = true;}
			}			
			return allow;
		}
	)
	
	.blur(
		function()
		{
			var val = jQuery(this).val();
			if(val != "")
			{
				if (!isDate(val,attributes.culture) || val.length<10)
					{attributes.callbackErrorFormat.apply(this,[this]);}
				else
					{attributes.callbackNoError.apply(this,[this]);}
			}
		}
	)
	
	.keyup(
		function()
		{
			var val = jQuery(this).val();
			if(val != "")
			{
				if(!isDate(val,attributes.culture))
					{attributes.callbackErrorFormat.apply(this,[this]);}
				else
					{attributes.callbackNoError.apply(this,[this]);}	
			}		
		}
	);
	return this;
};

// Declaring valid date character, minimum year and maximum year
var dtCh= "/";

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31;
		if (i==4 || i==6 || i==9 || i==11) 
      {this[i] = 30;}
		if (i==2) 
      {this[i] = 29;}
   } 
   return this;
}

function isDate(dtStr,culture)
{
	var daysInMonth = DaysArray(12);
	
	if(dtStr.length==10)
	{
		var strDay;
		var strMonth;
		var pos1=dtStr.indexOf(dtCh);
		var pos2=dtStr.indexOf(dtCh,pos1+1);
		
		if (culture && culture.toUpperCase()=="FR")
		{
			strDay = dtStr.substring(0,pos1);
			strMonth=dtStr.substring(pos1+1,pos2);
		}
		else
		{
			strMonth=dtStr.substring(0,pos1);
			strDay=dtStr.substring(pos1+1,pos2);
		}
		var strYear=dtStr.substring(pos2+1);
		strYr=strYear;
		
		if (strDay.charAt(0)=="0" && strDay.length>1) 
			{strDay=strDay.substring(1);}
		
		if (strMonth.charAt(0)=="0" && strMonth.length>1) 
			{strMonth=strMonth.substring(1);}
		
		for (var i = 1; i <= 3; i++) 
    {
			if (strYr.charAt(0)=="0" && strYr.length>1) 
        {strYr=strYr.substring(1);}
		}
		
		month=parseInt(strMonth);
		day=parseInt(strDay);
		year=parseInt(strYr);
		
		if (strMonth &&(month<1 || month>12))
      {return false;}
		if (strDay && (day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]))
      {return false;}
	}
	return true;
}

